package com.endurance.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @ProjectName: spring-cloud-hoxton-parent
 * @Package: com.endurance.controller
 * @ClassName: UserController
 * @Description:
 * @Author: sunlin
 * @CreateDate: 2024/02/05 09:00
 * @Version: 1.0
 */

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @GetMapping
    public String product() {
        System.out.println("用户接口");
        String productInfo = restTemplate.getForObject("http://" + loadBalance() + "/products", String.class);
        System.out.println(productInfo);
        return "users-ok";
    }

    private static String loadBalance() {
        List<String> hostAndPorts = new ArrayList<>();
        hostAndPorts.add("localhost:8990");
        hostAndPorts.add("localhost:8991");
        int i = new Random().nextInt(hostAndPorts.size());
        return hostAndPorts.get(i);
    }

    /**
     * 基于Ribbon的调用,三种方式
     * 1. DiscoveryClient : 服务发现的客户端对象，根据服务名称去服务注册中心获取服务列表到本地 没有负载均衡
     * 2. LoadBalanceClient: 负载均衡的客户端对象，根据服务名称去服务注册中心获取服务列表到本地，根据自己默认的负载均衡策略选择一台机器返回
     * 3. LoadBalance注解: 负载均衡客户端注解，使用RestTemplate
     */
    @GetMapping("ribbon")
    public String ribbon() {
        List<ServiceInstance> serviceInstances = discoveryClient.getInstances("PRODUCTS");
        serviceInstances.forEach(serviceInstance -> {
            System.out.println("当前服务uri:" + serviceInstance.getUri());
            System.out.println("当前服务主机:" + serviceInstance.getHost());
            System.out.println("当前服务端口:" + serviceInstance.getPort());
        });
        String forObject = new RestTemplate().getForObject(serviceInstances.get(0).getUri() + "/products", String.class);
        System.out.println(forObject);
        return "ribbon ok";
    }

    @GetMapping("ribbonLoadBalance")
    public String ribbonLoadBalance() {
        ServiceInstance ser = loadBalancerClient.choose("PRODUCTS");
        String forObject = new RestTemplate().getForObject(ser.getUri() + "/products", String.class);
        System.out.println(forObject);
        return "ribbon-load-balance ok";
    }

    @GetMapping("LoadBalance")
    public String LoadBalance() {
        String forObject = restTemplate.getForObject("http://PRODUCTS/products", String.class);
        System.out.println(forObject);
        return "ribbon-load-balance ok";
    }

}
